package com.wz.dhs.utils;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RLock;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @Description Redisson工具类
 * @author xyb
 * @since 10:02 2023/8/17
 */
@Component
@Slf4j
public class RedissonUtils implements ApplicationContextAware {

    public static RedissonClient redissonClient;

    /**
     * @Description 加锁执行
     * @author xyb
     * @since 10:06 2023/8/17
     */
    public static  <T> T lockExe(String key, Supplier<T> supplier){
        RLock lock = redissonClient.getLock(key);
        try {
            lock.lock();
            return supplier.get();
        }
        catch (Exception e){
            log.error("[加锁执行出现异常:{}]",e);
            throw e;
        }
        finally {
            if(lock.isHeldByCurrentThread() && lock.isLocked()){
                lock.unlock();
            }
        }
    }

    /**
     * 设置自增key,有效期1天
     * @param key
     * @throws BeansException
     */
    public static long incrementWithOneDayTime(String key){
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        long count = atomicLong.incrementAndGet();
        if(count == 1){
            //说明第一次创建key。设置有效期
            atomicLong.expire(1, TimeUnit.DAYS);
        }
        return count;
    }

    /**
     * set 设置值
     * @param key
     * @param value
     */
    public static void setValueSetWithTime(String key,String value){
        RSet<String> set = redissonClient.getSet(key);
        set.add(value);
        if(set.size() == 1){
            set.expire(1,TimeUnit.DAYS);
        }
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        redissonClient = applicationContext.getBean(RedissonClient.class);
    }
}
